package com.dongjiantong.app.handler;

import com.alibaba.dubbo.config.annotation.Reference;
import com.dongjiantong.common.exceptions.HttpCode;
import com.dongjiantong.common.exceptions.OPServerException;
import com.dongjiantong.common.redis.RedisUtil;
import com.dongjiantong.common.utils.BeanMapper;
import com.dongjiantong.common.utils.IntegerUtil;
import com.dongjiantong.common.utils.StringUtil;
import com.dongjiantong.common.web.model.BaseLoginUser;
import com.dongjiantong.common.web.sso.LoginInfo;
import com.dongjiantong.common.web.util.UserUtil;
import com.dongjiantong.openplatform.annotations.OpenParamHandler;
import com.dongjiantong.openplatform.core.ParamPreHandle;
import com.dongjiantong.user.enums.AppUserRole;
import com.dongjiantong.user.enums.FarmsEnum;
import com.dongjiantong.user.enums.OrgTypeEnum;
import com.dongjiantong.user.enums.UserEnum;
import com.dongjiantong.user.model.Farms;
import com.dongjiantong.user.model.MzUser;
import com.dongjiantong.user.model.OrgFramsUser;
import com.dongjiantong.user.model.OrganizationUser;
import com.dongjiantong.user.service.*;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author cao
 * @create 2017-12-15 上午11:28
 **/
@OpenParamHandler(patterns = "*", exclusions = {
        "get.session.id",
        "app.user.login"
})
@Slf4j
public class SessionHandle implements ParamPreHandle {

    @Reference(version = "1.0.0")
    public MzUserService mzUserService;
    @Reference(version = "1.0.0")
    public OrgUserAreaService orgUserAreaService;
    @Reference(version = "1.0.0")
    private OrgFramUserService orgFramUserService;
    @Reference(version = "1.0.0")
    private OrganizationUserService organizationUserService;
    @Reference(version = "1.0.0")
    private FarmsService farmsService;

    private MzUser queryUser(long userId)
    {
        String key = "mzuser:"+userId;
        MzUser mzUser = RedisUtil.getObject(key,MzUser.class);

        if(mzUser != null)
        {
            return  mzUser;
        }
        else
        {
            mzUser=  mzUserService.getMzUser(userId);
            if(mzUser!=null)
            {
                RedisUtil.setObject(key,mzUser);
            }
        }

        return mzUser;
    }

    @Override
    public void handle(Map<String, Object> params) throws OPServerException {
        if (params.get("sid") == null || StringUtil.isEmpty((String) params.get("sid"))) {
            throw new OPServerException(HttpCode.BAD_REQUEST, "参数不正确(sid)");
        }
        String sessionId = params.get("sid").toString();
        String key=SessionsModel.TOKEN_PREFIX+":"+sessionId;
        Map<String, Object> snapshot= Maps.newHashMap();

            snapshot = RedisUtil.getMaps(key);
            if (snapshot == null || snapshot.size() == 0 || snapshot.get(SessionsModel.USER_ID) == null) {
                throw new OPServerException(HttpCode.BAD_REQUEST, "登录已经过期，请重新登录");
            }

//        // refresh
//        sessionManager.refreshExpireTime(Sessions.TOKEN_PREFIX, sessionId, SessionsModel.LONG_INACTIVE_INTERVAL);
        Long uid = IntegerUtil.toLong(snapshot.get(SessionsModel.USER_ID).toString());
        MzUser mzUser = queryUser(uid);
        if (mzUser==null) {
            log.error("fail to find user by id={},cause:{}",
                    uid, "用户不存在");
            throw new OPServerException(HttpCode.BAD_REQUEST,"用户名不存在");
        }
        String role = null;
        if (params.get("role") == null) {
            role = null;
        } else {
            role = params.get("role").toString();
        }
        Integer role1 = null;
        if (role == null || role.isEmpty()) {
            role1 = null;
        } else {
            role1 = Integer.parseInt(role);
        }

        LoginInfo loginUser = (LoginInfo) wrapLoginUser(mzUser , role1);
        UserUtil.putCurrentUser(loginUser);
        System.out.println(UserUtil.getCurrentUser().toString());
    }
    private BaseLoginUser wrapLoginUser(MzUser user , Integer role) {
       // BaseLoginUser baseLoginUser = LoginUserMaker.from(user);
        LoginInfo loginUser = BeanMapper.map(user, LoginInfo.class);

        Integer userType = user.getUserType();

        //farms user wrap
        if(userType.equals(UserEnum.USERTYPE_CUS.getCode())) {
            loginUser = wrapFarmUser(loginUser,role);
        }

        //butcher user wrap
        if(userType.equals(UserEnum.USERTYPE_BUT.getCode())){
            loginUser = wrapButcherUser(loginUser,role);
        }

        //gov user wrap
        if (userType.equals(UserEnum.USERTYPE_ORG.getCode())){
            loginUser = wrapGovUser(loginUser , role);
        }

        return loginUser;
    }

    private LoginInfo wrapFarmUser(LoginInfo loginUser, Integer role) {
        //todo
        return loginUser;
    }

    private LoginInfo wrapButcherUser(LoginInfo loginUser, Integer role) {
        //todo
        return loginUser;
    }

    private LoginInfo wrapGovUser(LoginInfo loginUser, Integer role) {
        try{
            List<Long> breedFactoryIds = new ArrayList<>();
            List<Long> butcherFactoryIds = new ArrayList<>();
            List<Long> declareStationIds = new ArrayList<>();
            List<Long> certificateStationIds = new ArrayList<>();
            List<Long> collectPointIds = new ArrayList<>();
            List<Long> streamBusinessIds = new ArrayList<>();
            breedFactoryIds.add(-1L);
            butcherFactoryIds.add(-1L);
            declareStationIds.add(-1L);
            certificateStationIds.add(-1L);
            collectPointIds.add(-1L);
            streamBusinessIds.add(-1L);
            if (AppUserRole.ASSOCIATION_INSPECTOR.value().equals(role)){
                List<OrgFramsUser> orgFramsUsers = orgFramUserService.findFarmsByUserId(loginUser.getId());
                if(orgFramsUsers != null){
                    for(OrgFramsUser orgFramsUser : orgFramsUsers) breedFactoryIds.add(orgFramsUser.getFarmId());
                }
            }else if (AppUserRole.VETERINARIAN.value().equals(role)){

                List<OrganizationUser> organizationUserList =
                        organizationUserService.selectByUserId(loginUser.getId());
                if(organizationUserList != null){
                    for(OrganizationUser organizationUser : organizationUserList){
                        if (organizationUser.getType().equals(OrgTypeEnum.OrgType_declaration.getCode()))
                            declareStationIds.add(organizationUser.getOrgId());
                        else if (organizationUser.getType().equals(OrgTypeEnum.OrgType_cert.getCode()))
                            certificateStationIds.add(organizationUser.getOrgId());
                        else if (organizationUser.getType().equals(OrgTypeEnum.OrgType_collection.getCode()))
                            collectPointIds.add(organizationUser.getOrgId());
                    }
                }
                List<Farms> farmsList = farmsService.selectByMap(buildMap(loginUser));
                if(farmsList != null){
                    for(Farms farms : farmsList) {
                        if(farms.getFarmsType().equals(FarmsEnum.Breed.getCode()) || farms.getFarmsType().equals(FarmsEnum.Retail.getCode()))
                            breedFactoryIds.add(farms.getId());
                        else if (farms.getFarmsType().equals(FarmsEnum.logistics.getCode()))
                            streamBusinessIds.add(farms.getId());
                    }
                }
                List<OrgFramsUser> orgFramsUsers = orgFramUserService.findFarmsByUserId(loginUser.getId());
                if(orgFramsUsers != null){
                    for(OrgFramsUser orgFramsUser : orgFramsUsers) butcherFactoryIds.add(orgFramsUser.getFarmId());
                    loginUser.setButcherFactoryIds(butcherFactoryIds);

                }
            }else if (AppUserRole.PREVENTION_COORDINATOR.value().equals(role)){
                List<OrgFramsUser> orgFramsUsers = orgFramUserService.findFarmsByUserId(loginUser.getId());
                if(orgFramsUsers != null){
                    for(OrgFramsUser orgFramsUser : orgFramsUsers) breedFactoryIds.add(orgFramsUser.getFarmId());
                }
            }else if(AppUserRole.COLLECT_POINT.value().equals(role)){
                List<Farms> farmsList = farmsService.selectByMap(buildMap(loginUser));
                if(farmsList != null){
                    for(Farms farms : farmsList) {
                        if(farms.getFarmsType().equals(FarmsEnum.Breed.getCode()) || farms.getFarmsType().equals(FarmsEnum.Retail.getCode()))
                            breedFactoryIds.add(farms.getId());
                        else if (farms.getFarmsType().equals(FarmsEnum.logistics.getCode()))
                            streamBusinessIds.add(farms.getId());
                    }
                }

            }else {
                // 县级以上的人员
            }

            loginUser.setBreedFactoryIds(breedFactoryIds);
            loginUser.setButcherFactoryIds(butcherFactoryIds);
            loginUser.setDeclareStationIds(declareStationIds);
            loginUser.setCollectStationIds(collectPointIds);
            loginUser.setCertificateStationIds(certificateStationIds);
            loginUser.setStreamBusinessIds(streamBusinessIds);

            List<Object> userAreaList = orgUserAreaService.queryLocationArea(loginUser.getId());
            loginUser.setAreaList(userAreaList);

            return loginUser;
        }catch (Exception e){
            e.printStackTrace();
            throw new OPServerException(HttpCode.INTERNAL_SERVER_ERROR.getCode(),HttpCode.INTERNAL_SERVER_ERROR.getMessage());
        }
    }

    private Map<String , Object> buildMap(LoginInfo loginUser) {
        Map<String , Object> map = Maps.newHashMap();
        map.put("userId", loginUser.getId());
        return map;
    }
}
